package com.wwlwxg.logback;

import com.sun.xml.internal.ws.util.CompletedFuture;
import javassist.expr.NewExpr;
import org.junit.Test;

import java.sql.Time;
import java.util.concurrent.*;
import java.util.jar.JarEntry;

public class ThreadPoolTest {

	@Test
	public void testArrayBlockingQueue() {

		ArrayBlockingQueue queue = new ArrayBlockingQueue(3);

		ThreadPoolExecutor executor = new ThreadPoolExecutor(
				2,
				5,
				10,
				TimeUnit.SECONDS,
				queue,
				Executors.defaultThreadFactory(),
				new ThreadPoolExecutor.AbortPolicy());

		print(executor);

		for (int i = 0; i < 100; i++) {
			final int j = i;
			executor.execute(() -> {
				System.out.println("=========================================");
				System.out.println(Thread.currentThread().getName() + " : " + j + " enter");

//				try {
//					TimeUnit.MILLISECONDS.sleep(1);
//				} catch (InterruptedException e) {
//					e.printStackTrace();
//				}
				System.out.println(Thread.currentThread().getName() + " : " + j + " end");
				System.out.println("=========================================");
			});
			print(executor);

		}
		System.out.println("ok");
	}


	@Test
	public void testCompeleteFuture() throws ExecutionException, InterruptedException {
		// 没有返回值
		CompletableFuture<Void> future1 = CompletableFuture.runAsync(()->{
			System.out.println(Thread.currentThread().getName() + " future");
		});

		future1.get();

		// 有返回值
		CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(()->{
			return 1024/0;
		});

		Integer result = future2.whenComplete((t, u) -> {
			System.out.println("====> t = " + t + ", u = " + u);
		}).get();

		System.out.println(result);
	}



	@Test
	public void testForkjoin() throws ExecutionException, InterruptedException {
		MyTask myTask = new MyTask(1, 100000000);
		ForkJoinPool pool = new ForkJoinPool(8);
		long beginTime = System.currentTimeMillis();
		Integer integer = pool.submit(myTask).get();
		System.out.println(System.currentTimeMillis() - beginTime);
		System.out.println(integer);
		pool.shutdown();
	}

	class MyTask extends RecursiveTask<Integer> {

		private int begin;
		private int end;

		private int VALUE = 10;

		private int result = 0;

		public MyTask(Integer begin, Integer end) {
			this.begin = begin;
			this.end = end;
		}

		@Override
		protected Integer compute() {
			if((end - begin) < VALUE) {
				for (int i = begin; i <= end; i++) {
					result += i;
				}
			} else {
				int middle = (end + begin) / 2;
				MyTask task1 = new MyTask(begin, middle);
				MyTask task2 = new MyTask(middle + 1, end);
				task1.fork();
				task2.fork();

				result = task1.join() + task2.join();
			}

			return result;
		}
	}

	public static void print(ThreadPoolExecutor executor) {
		String desc = "getActiveCount: " + executor.getActiveCount() + "\n"
//				+ "| getCorePoolSize = " + executor.getCorePoolSize() + "\n"
//				+ "| getMaximumPoolSize = " + executor.getMaximumPoolSize() + "\n"
//				+ "| getKeepAliveTime = " + executor.getKeepAliveTime(TimeUnit.SECONDS) + "\n"
				+ "| getLargestPoolSize = " + executor.getLargestPoolSize() + "\n"
				+ "| getPoolSize = " + executor.getPoolSize() + "\n"
				+ "| getQueue = " + executor.getQueue() + "\n"
				+ "| getRejectedExecutionHandler = " + executor.getRejectedExecutionHandler() + "\n"
				+ "| getTaskCount = " + executor.getTaskCount() + "\n"
				+ "| getThreadFactory = " + executor.getThreadFactory();
		System.out.println(desc);
	}
}
